package com.demo.connectdbtest.module.ssh.controller;

import bsh.commands.dir;
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.SCPClient;
import ch.ethz.ssh2.SCPInputStream;
import ch.ethz.ssh2.SCPOutputStream;
import ch.ethz.ssh2.SFTPv3Client;
import ch.ethz.ssh2.Session;
import org.apache.commons.io.FileUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Collection;

@RestController
@RequestMapping("/scpc")
public class SCPClientController {


    @GetMapping("/upload")
    public String upload() {
//连接服务器 服务器名称和端口号
        //xx.xx.xx.xx 就是目标服务器的ip 端口是22
        Connection connection = new Connection("xx.xx.xx.xx", 22);
        //你要上传文件所在地址，linux和window路径不一样看你自己的系统
        String filePath1 = "C:/JepsFile/202007211503.png";
        File f = new File(filePath1);
        try (FileInputStream fis = new FileInputStream(f)) {
            connection.connect();
            //yuan服务器用户名和密码
            boolean isAuthenticated = connection.authenticateWithPassword("root", "root");
            if (!isAuthenticated) {
                System.out.println("连接建立失败");
                return "连接建立失败";
            }
            SCPClient scpClient = new SCPClient(connection);
            //这个是你要上传文件的目标服务器的文件路径
            String remoteTargetDirectory = "/app/JepsUpload/sup/202007/";
            SFTPv3Client sftpv3Client = new SFTPv3Client(connection);
            //判断是否有这个文件夹 如果没有就创建一个
            //TODO 暂时注释掉
//            Boolean isdir = isDir(sftpv3Client, remoteTargetDirectory);
//            if(!isdir){
//                sftpv3Client.mkdir(remoteTargetDirectory,0600);
//            }
            SCPOutputStream os = scpClient.put(f.getName(), f.length(), remoteTargetDirectory, null);
            byte[] b = new byte[4096];
            int i;
            while ((i = fis.read(b)) != -1) {
                os.write(b, 0, i);
            }
            Session session = connection.openSession();//打开一个会话
            //远程执行linux命令 因为上传的文件没有读的文件 需要加上才能下载 （如果你上传的文件有）
            String cmd = "chmod +r " + remoteTargetDirectory + f.getName();
            System.out.println("linux命令==" + cmd);
            session.execCommand(cmd);//执行命令
            os.flush();
            fis.close();
            os.close();
            connection.close();
            System.out.println("upload ok");
        } catch (IOException e) {
            System.out.println(e.toString());
        }
        return "程序执行完毕";
        // 原文链接：https://blog.csdn.net/azlnhaha/article/details/107503850
    }

    @GetMapping("/download")
    public String download() {
        Connection connection = new Connection("192.168.63.33", 22);
        //客户端要存储的下载文件的路径可以自己随便定义
        File newFile = new File("D:/JepsFile");
        try (FileOutputStream fos = new FileOutputStream(newFile);) {
            connection.connect();
            boolean isAuthenticated = connection.authenticateWithPassword("root", "123456");
            if (isAuthenticated) {
                SCPClient scpClient = connection.createSCPClient();
                //从目标文件服务器下载文件
                SCPInputStream sis = scpClient.get("/data/project/军队文职考试大纲");
                //先将远程服务器的文件下载到用户的电脑某个磁盘内
                File f = new File("D:/JepsFile");
                if (!f.exists()) {
                    f.mkdirs();
                }
                byte[] b = new byte[4096];
                int i;
                while ((i = sis.read(b)) != -1) {
                    fos.write(b, 0, i);
                }
                fos.flush();
                fos.close();
                sis.close();
                connection.close();
                System.out.println("download ok");
            } else {
                System.out.println("连接建立失败");
            }
        } catch (IOException e) {
            System.out.println("下载文件异常=" + e.toString());
            return "error";
        }
        return "ok";
    }


    //下载jar success 但是解压不行
    @GetMapping("/down")
    public String down() {
        try {
            // 远程机器ip
            String ip = "10.252.176.46";
            // ssh端口
            int port = 22;
            // ssh登录 用户名 密码
            String pwd = "Anjian@20230411^";
            String user = "root";
            String system = "passenger";
//            String jarName = "passenger-management-bootstrap-V3.1.3.113.jar";
            String jarName = "passenger-management-bootstrap-3.1.2-SNAPSHOT.jar";
            String dowloadJarPath = "/data/project/security-check/jar-file/" + jarName;
            String storageDir = "D:\\data\\testClasses\\";
            String storagePath = storageDir + system + "\\";
            String storageJarPath = storagePath + jarName;
            File storageFile = new File(storagePath);
            File storageFileDir = new File(storageDir);
            if (!storageFileDir.exists()) {
                storageFileDir.mkdirs();
            }
            if (!storageFile.exists()) {
                storageFile.mkdirs();
            }

            // 创建链接
            Connection conn = new Connection(ip, port);
            conn.connect();
            // 登录
            conn.authenticateWithPassword(user, pwd);

            // 获取SCPClient
            SCPClient sc = conn.createSCPClient();
            // 获取远程机器上的文件流 (远程文件地址的绝对路径)
            SCPInputStream is = sc.get(dowloadJarPath);
            // 创建本机文件写入流
            FileOutputStream os = new FileOutputStream(new File(storageJarPath));
            // 将文件写入本地
            byte[] b = new byte[4096];
            int i;
            while ((i = is.read(b)) != -1) {
                os.write(b, 0, i);
            }
            os.flush();
            // copy完成，关闭相应资源
            is.close();
            os.close();
            conn.close();
            System.out.println("copy ok");
            //原文链接：https://blog.csdn.net/TutinBing/article/details/95726639

            //NEW进行本地的字节码解压操作
            String uncompressPath = "E:\\data\\uncompressClasses\\";
            // String path = "D:\\data\\testClasses\\"+system+"\\";
            /*int index = storageJarPath.lastIndexOf(File.separator);
            String path = storageJarPath.substring(0, index);*/
            String path = storagePath;
   /*          String jar = storageJarPath.substring(index);
            //可以去掉前面已经校验
           File dir = new File(path);
            if (!dir.exists()) {
                System.out.println("创建问渐渐");
                dir.mkdirs();
            }
             String jarPath = path + jarName;*/
            String jarPath = storageJarPath;
            // String jarPath = path + "passenger-management-bootstrap-V3.1.3.113.jar";
            StringBuilder cmd = new StringBuilder();
            cmd.append("cmd /c cd " + path + " && jar -xvf " + jarPath);
            Process exec = Runtime.getRuntime().exec(String.valueOf(cmd));

            //输出是为了解决卡住问题
            InputStream in = exec.getInputStream();
            InputStreamReader inReader = new InputStreamReader(in);
            BufferedReader inBr = new BufferedReader(inReader);
            String strIn;
            while ((strIn = inBr.readLine()) != null) {
                System.out.println(strIn);
            }

            FileUtils.copyDirectoryToDirectory(new File(path + "\\BOOT-INF\\classes\\com"), new File(path));


            //true 代表递归 false 代表不递归
            Collection<File> files = FileUtils.listFiles(new File(path + "BOOT-INF\\lib\\"), null, false);
            StringBuilder executeCmd = new StringBuilder();
            executeCmd.append("cmd /c cd " + path);
            for (File file : files) {
                System.out.println(file.getName());
                if (file.getName().contains("passenger")) {
                    FileUtils.copyFileToDirectory(file, new File(path));
                    executeCmd.append(" &&  jar -xvf " + path + File.separator + file.getName());
                }
            }
            System.out.println("executeCmd命令：" + executeCmd.toString());
            Process result = Runtime.getRuntime().exec(String.valueOf(executeCmd));
            System.out.println(result);
            System.out.println(exec);
            //复制字节码文件到其他的地方
            FileUtils.copyDirectoryToDirectory(new File(path + "com"), new File(uncompressPath + system + "\\"));


            //操作完成后删除解压的文件
            String[] list = storageFileDir.list();
            //递归删除目录中的子目录下
            for (String name : list) {
                delete(new File(storageFileDir, name));
            }
            // 最外面的文件夹此时为空，可以删除
            storageFileDir.delete();
            System.out.println("递归删除文件完成");


        } catch (Exception e) {
            System.out.println("下载文件异常=" + e.toString());
            e.printStackTrace();
            return "error";
        }
        return "ok";
    }

    public static void delete(File file) {
        if (file.isDirectory()) {
            for (String sub : file.list()) {
                delete(new File(file, sub));
            }
            file.delete();
        }
        if (file.isFile()) {
            System.out.println("删除的文件："+file.getName());
            // System.out.println(f.getAbsolutePath()+"是文件");
            file.delete();
        }
    }
    //原文链接：https://blog.csdn.net/qq_44242303/article/details/119212344


}
